package com.master.equipment.netty.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;

@Component
public class NettyServer {

	//
	private EventLoopGroup boss = new NioEventLoopGroup();
	/**
	 * work 线程组用于数据处理
	 */
	private EventLoopGroup work = new NioEventLoopGroup();

	/**
	 * 启动Netty Server
	 *
	 * @throws InterruptedException
	 */
	//@PostConstruct （后续修改成异步）
	public void start(InetSocketAddress inetSocketAddress) {
		try {
			ServerBootstrap bootstrap = new ServerBootstrap();
			bootstrap.group(boss, work)
					// 指定Channel
					.channel(NioServerSocketChannel.class)
					//使用指定的端口设置套接字地址
					.localAddress(inetSocketAddress)
					// 日志处理 info级别
					.handler(new LoggingHandler(LogLevel.INFO))
                    //服务端可连接队列数,对应TCP/IP协议listen函数中backlog参数
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    //设置TCP长连接,一般如果两个小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    //将小的数据包包装成更大的帧进行传送，提高网络的负载,即TCP延迟传输
                    .childOption(ChannelOption.TCP_NODELAY, false)
                    .childOption(ChannelOption.AUTO_READ, true)
					// 添加自定义的初始化器
					.childHandler(new NettyServerInitializer());

			System.out.println("--------------------自定义配置成功---------------------");
			ChannelFuture future = bootstrap.bind(inetSocketAddress).sync();
			System.out.println(" tcp服务器开始监听端口：" + inetSocketAddress.getPort());
			if (future.isSuccess()) {
				System.out.println("--------------------启动成功---------------------");
			}
		} catch (Exception e) {
			e.printStackTrace();
			boss.shutdownGracefully();
			work.shutdownGracefully();
		}

	}

	//@PreDestroy （后续修改成异步）
	public void destory() throws InterruptedException {
		boss.shutdownGracefully().sync();
		work.shutdownGracefully().sync();
		System.out.println("----关闭Netty-----");
	}

}
